function GoogleAuth()
{
    var this_auth_obj = this;

    this.email = "";
    this.pass = "";
    this.logintoken = "";
    this.loggedincallback;
    this.errormsg = "";
    this.captchatoken = "";
    this.captchaurl = "";
    this.captcharesponse = "";

    this.setCredentials = function (username, password)
    {
        this.clear();
        data = new air.ByteArray();
        data.writeUTFBytes( username );
        air.EncryptedLocalStore.setItem( 'email', data );
        this.email = username;
        data = new air.ByteArray();
        data.writeUTFBytes( password );
        air.EncryptedLocalStore.setItem( 'password', data );
        this.pass = password;
    }

    this.retrieveCredentials = function ()
    {
        air.trace("Getting credentials out of store");
        var emailstore = air.EncryptedLocalStore.getItem( 'email' );
        var passstore = air.EncryptedLocalStore.getItem( 'password' );
        if (emailstore != null) {
            this.email = emailstore.readUTFBytes( emailstore.bytesAvailable );
            if (passstore != null) {
                this.pass = passstore.readUTFBytes(passstore.bytesAvailable);
            } else {
                air.trace("Password store was null", passstore);
            }
        } else {
            air.trace("email store was null", emailstore);
        }
        air.trace("Retrived credentials from storage", this.email);
    }

    this.connect = function (finish_callback)
    {
        this.loggedincallback = finish_callback;
        this.retrieveCredentials();
        this.googleLogin();
    }

    this.login = function (finish_callback)
    {
        this.loggedincallback = finish_callback;
        this.askUser();
    }
        
    this.askUser = function ()
    {
        this.clear();

        var options = new air.NativeWindowInitOptions();
        var loginWin = null;
        var width = 450;
        var height = 450;
        
        options.type = air.NativeWindowType.NORMAL;
        air.trace("Creating native window");
        loginWin = new air.NativeWindow(options);
        loginWin.addEventListener(air.Event.CLOSE, function(event){this_auth_obj.userAsked(event);});
        loginWin.title="Log Into Google";
        loginWin.width = width;
        loginWin.height = height;
        air.trace("Creating HTML Loader");
        htmlloader = new air.HTMLLoader();
        htmlloader.width = width-10;
        htmlloader.height = height-10;
        loginWin.stage.align = window.runtime.flash.display.StageAlign.TOP_LEFT;
        loginWin.stage.scaleMode = window.runtime.flash.display.StageScaleMode.NO_SCALE;
        air.trace("Adding HTML Loader to Native Window");
        loginWin.stage.addChild(htmlloader);
        htmlloader.load(new air.URLRequest(
            "lib/gdata/login.html"
        ));
        
        loginWin.activate();
    }

    this.userAsked = function (event)
    {
        this.connect(this.loggedincallback);
    }

    this.googleLogin = function ()
    {
        params = {
            accountType: 'HOSTED_OR_GOOGLE',
            Email: this.email,
            Passwd: this.pass,
            service: 'writely',
            source: 'com.googlecode.gdocsuploader-air-v0.1'};
        if (this.captcharesponse != "") {
            params.logintoken = this.captchatoken;
            params.logincaptcha = this.captcharesponse;
            air.trace("Sending captcha stuff", params);
            this.captchatoken = "";
        }
        joe = new Ajax.Request('https://www.google.com/accounts/ClientLogin', {
            method: 'post',
            contentType: 'application/x-www-form-urlencoded',
            parameters: params,
            onSuccess: function(response) {
                this_auth_obj.logintoken = response.responseText.match(/Auth=(.*)/)[1];
                air.trace("Login token: "+this_auth_obj.logintoken);
                this_auth_obj.loggedIntoGoogle(true);
            },
            onFailure: function(response) {
                air.trace("Login failure");
                air.trace(response);
                this_auth_obj.errormsg = "Unknown login error";
                this_auth_obj.loggedIntoGoogle(false);
            },
            onComplete: function(response) {
                air.trace("Login (attempt) Complete");
            },
            on403: function (response) {
                why = response.responseText.match(/Error=(.*)/)[1];
                air.trace("Could not log in for the following code:"+why+":");
                this_auth_obj.captchatoken = "";
                this_auth_obj.captchaurl = "";
                this_auth_obj.captcharesponse = "";
                switch (why) {
                    case 'BadAuthentication':
                        this_auth_obj.errormsg = "The login username or password is not recognized.";
                        air.trace("Bad Authentication", this_auth_obj.errormsg);
                        this_auth_obj.loggedIntoGoogle(false);
                        break;
                    case 'NotVerified':
                    case 'TermsNotAgreed':
                    case 'AccountDisabled':
                    case 'AccountDeleted':
                    case 'ServiceDisabled':
                        this_auth_obj.errormsg = "The provided account is not enabled for document uploading";
                        this_auth_obj.loggedIntoGoogle(false);
                        break;
                    case 'CaptchaRequired':
                        this_auth_obj.errormsg = "A Captcha response is required";
                        this_auth_obj.captchatoken = response.responseText.match(/CaptchaToken=(.*)/)[1];
                        this_auth_obj.captchaurl = "http://www.google.com/accounts/" + response.responseText.match(/CaptchaUrl=(.*)/)[1];
                        this_auth_obj.loggedIntoGoogle(false);
                        break;
                    case 'ServiceUnavailable':
                        this_auth_obj.errormsg = "Upload service not available.  Please try again later.";
                        this_auth_obj.loggedIntoGoogle(false);
                        break;
                    default:
                        this_auth_obj.errormsg = "Unknown login error";
                        this_auth_obj.loggedIntoGoogle(false);
                }
            }
        });
        air.trace("ajax object", joe);
    }

    this.loggedIntoGoogle = function(success)
    {
        if (this.loggedincallback != null) {
            this.loggedincallback(success);
        } else {
            air.trace("login callback function is null");
        }
    }

    this.getAuthHeader = function ()
    {
        return "Authorization: GoogleLogin auth="+this.logintoken;
    }
    
    this.clear = function()
    {
        air.EncryptedLocalStore.removeItem('email');
        air.EncryptedLocalStore.removeItem('password');
        this.email = "";
        this.pass = "";
        this.logintoken = "";
    }

    return true;
}